using System;
using System.Collections.Generic;
using System.Text;
using log4net.Layout;
using System.Windows.Forms;

namespace SharpMud.Server.App.GUI
{
    public class TextBoxLogAppender : log4net.Appender.AppenderSkeleton
    {
        Queue<log4net.Core.LoggingEvent> _QueuedLoggedEvents;
        System.Windows.Forms.TextBox _TextBox;
        List<string> _textboxLines;

        private TextBoxLogAppender()
            :base()
        {
            _QueuedLoggedEvents = new Queue<log4net.Core.LoggingEvent>();
            _textboxLines = new List<string>();
        }

        public TextBoxLogAppender(ILayout layout, System.Windows.Forms.TextBox textBox)
            :this()
        {
            if (layout == null)
                throw new ArgumentNullException("layout");
            if (textBox == null)
                throw new ArgumentNullException("textBox");
            this.Layout = layout;
            this._TextBox = textBox;
        }

        protected override bool RequiresLayout
        {
            get
            {
                return true;
            }
        }

        protected override void Append(log4net.Core.LoggingEvent loggingEvent)
        {
            if (this._TextBox.IsDisposed)
            {
                this.Close();
                return;
            }
            lock (this._QueuedLoggedEvents)
            {
                this._QueuedLoggedEvents.Enqueue(loggingEvent);
            }
            this._TextBox.Invoke(new MethodInvoker(this.UpdateTextBox));
        }

        public void UpdateTextBox()
        {
            lock (_QueuedLoggedEvents)
            {
                lock (_TextBox)
                {
                    if(_TextBox.Multiline==false)
                        _TextBox.Multiline = true;
                    if(_TextBox.ScrollBars!=System.Windows.Forms.ScrollBars.Both)
                        _TextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
                    if (_TextBox.WordWrap == true)
                        _TextBox.WordWrap = false;
                    if(_TextBox.ReadOnly==false)
                        _TextBox.ReadOnly = true;

                    _textboxLines.Clear();
                    _textboxLines.AddRange(_TextBox.Lines);
                    while (_QueuedLoggedEvents.Count > 0)
                    {
                        log4net.Core.LoggingEvent loggingEvent = _QueuedLoggedEvents.Dequeue();
                        _textboxLines.Add(String.Format("{0:5} | {1}> {2}", loggingEvent.Level.DisplayName.ToUpper(),loggingEvent.LoggerName,loggingEvent.RenderedMessage));
                    }
                    _TextBox.Lines = _textboxLines.ToArray();

                    _TextBox.Select();
                    _TextBox.SelectionStart = _TextBox.TextLength;
                    _TextBox.ScrollToCaret();
                }
            }
        }
    }
}
